package cn.rulian.base.common.util;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
 * 高频常用方法集合<br>
 */
public class xx {
	
	
	/**
	 * 私有化默认构造函数，不允许创建工具类对象。
	 */
	private xx(){}
	

	/**
	 * 对象是否为空
	 * @param obj String,List,Map,Object[],int[],long[]
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static boolean isEmpty(Object o) {
		if (o == null) {
			return true;
		}
		if (o instanceof String) {
			if (o.toString().trim().equals("")) {
				return true;
			}
		} else if (o instanceof List) {
			if (((List) o).size() == 0) {
				return true;
			}
		} else if (o instanceof Map) {
			if (((Map) o).size() == 0) {
				return true;
			}
		} else if (o instanceof Set) {
			if (((Set) o).size() == 0) {
				return true;
			}
		} else if (o instanceof Object[]) {
			if (((Object[]) o).length == 0) {
				return true;
			}
		} else if (o instanceof int[]) {
			if (((int[]) o).length == 0) {
				return true;
			}
		} else if (o instanceof long[]) {
			if (((long[]) o).length == 0) {
				return true;
			}
		} else if(o instanceof Integer) {
			if (o.toString().trim().equals("0")) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 对象组中是否存在 Empty Object
	 * @param os 对象组
	 * @return
	 */
	public static boolean isOneEmpty(Object... os) {
		for (Object o : os) {
			if(isEmpty(o)){
				return true;
			}
		}
		return false;
	}

	/**
	 * 对象组中是否全是 Empty Object
	 * @param os
	 * @return
	 */
	public static boolean isAllEmpty(Object... os) {
		for (Object o : os) {
			if (!isEmpty(o)) {
				return false;
			}
		}
		return true;
	}
	
	
	/**
	 * 字符串是否为 true
	 * @param str
	 * @return
	 */
	public static boolean isTrue(Object str) {
		if (isEmpty(str)) {
			return false;
		}
		str = str.toString().trim().toLowerCase();
		if (str.equals("true") || str.equals("on")) {
			return true;
		}
		return false;
	}

	
	/**
	 * 强转->Integer
	 * @param obj
	 * @return
	 */
	public static Integer toInt(Object obj) {
		return Integer.parseInt(obj.toString());
	}

	/**
	 * 强转->Integer
	 * @param obj
	 * @param defaultValue
	 * @return
	 */
	public static Integer toInt(Object obj, int defaultValue) {
		if (isEmpty(obj)) {
			return defaultValue;
		}
		return toInt(obj);
	}

	/**
	 * 强转->Long
	 * @param obj
	 * @return
	 */
	public static long toLong(Object obj) {
		return Long.parseLong(obj.toString());
	}

	/**
	 * 强转->Long
	 * @param obj
	 * @param defaultValue
	 * @return
	 */
	public static long toLong(Object obj, long defaultValue) {
		if (isEmpty(obj)) {
			return defaultValue;
		}
		return toLong(obj);
	}

	/**
	 * 强转->Double
	 * @param obj
	 * @return
	 */
	public static double toDouble(Object obj) {
		return Double.parseDouble(obj.toString());
	}
	
	/**
	 * 强转->Boolean
	 * @param obj
	 * @return
	 */
	public static Boolean toBoolean(Object obj) {
		return Boolean.parseBoolean(obj.toString());
	}
	
	/**
	 * 强转->Boolean
	 * @param obj
	 * @param defaultValue
	 * @return
	 */
	public static Boolean toBoolean(Object obj, Boolean defaultValue) {
		if (isEmpty(obj)) {
			return defaultValue;
		}
		return toBoolean(obj);
	}
	
	/**
	 * 强转->java.util.Date
	 * @param str 日期字符串
	 * @return
	 */
	public static Date toDate(String str) {
		try {
			if (str == null || "".equals(str.trim()))
			{
				return null;
			}
			return new java.text.SimpleDateFormat("yyyy-MM-dd").parse(str.trim());
		} catch (Exception e) {
			throw new RuntimeException("Can not parse the parameter \"" + str + "\" to Date value.");
		}
	}
	
	public static Date toTime(String str) {
		try {
			if (str == null || "".equals(str.trim()))
			{
				return null;
			}
			return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(str.trim());
		} catch (Exception e) {
			throw new RuntimeException("Can not parse the parameter \"" + str + "\" to Time value.");
		}
	}
	

	
	/**
	 * Array转字符串(用指定符号分割)
	 * @param array
	 * @param sign
	 * @return
	 */
	public static String join(Object[] array, char sign) {
		if (array == null) {
			return null;
		}
		int arraySize = array.length;
		int bufSize = (arraySize == 0 ? 0 : ((array[0] == null ? 16 : array[0].toString().length()) + 1) * arraySize);
		StringBuilder sb = new StringBuilder(bufSize);

		for (int i = 0; i < arraySize; i++) {
			if (i > 0) {
				sb.append(sign);
			}
			if (array[i] != null) {
				sb.append(array[i]);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 删除末尾字符串
	 * @param str 待处理字符串
	 * @param sign 需要删除的符号
	 * @return
	 */
	public static String delEnd(String str, String sign){
		if (str.endsWith(sign)) {
			return str.substring(0, str.lastIndexOf(sign));
		}
		return str;
	}

	
	/**
	 * 消耗毫秒数
	 * @param time
	 */
	public static void costTime(long time,String location) {
		System.err.println("位置："+location+"耗时:" + (System.currentTimeMillis() - time) + "ms\n");
	}
	
	/**
	 * 格式化输出JSON
	 * @param json
	 * @return
	 */
	public static String formatJson(String json) {
		int level = 0;
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < json.length(); i++) {
			char c = json.charAt(i);
			if (level > 0 && '\n' == sb.charAt(sb.length() - 1)) {
				sb.append(getLevelStr(level));
			}
			switch (c) {
			case '{':
			case '[':
				sb.append(c + "\n");
				level++;
				break;
			case ',':
				sb.append(c + "\n");
				break;
			case '}':
			case ']':
				sb.append("\n");
				level--;
				sb.append(getLevelStr(level));
				sb.append(c);
				break;
			default:
				sb.append(c);
				break;
			}
		}
		return sb.toString();
	}
    
    private static String getLevelStr(int level){
        StringBuffer levelStr = new StringBuffer();
        for(int levelI = 0;levelI<level ; levelI++){
            levelStr.append("  ");
        }
        return levelStr.toString();
    }
    
	/**
	 * 格式化 日期
	 */
    public static String getDateStr(Date date)
	{
    	if(date == null)
    	{
    		return "";
    	}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		return formatter.format(date);
	}

	/**
	 * 格式化 时间
	 */
    public static String getTimeStr(Date date)
	{
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return formatter.format(date);
	}
    




    
	/**
	 * 得到对象给定字段名的值。
	 * @param obj 对象
	 * @param fieldName	字段名，可以多层，以点分开，符合ognl标准
	 * @return
	 * @throws Exception
	 */
	public static Object getFieldValue(Object obj, String fieldName) throws Exception
	{
		if (obj == null)
		{
			return null;
		}
		if (fieldName.indexOf(".") != -1)
		{//此时说明取的是属性的属性
			String nameOne = fieldName.substring(0, fieldName.indexOf("."));
			String nameOther = fieldName.substring(fieldName.indexOf(".") + 1);
			java.lang.reflect.Field f = obj.getClass().getDeclaredField(nameOne);
			f.setAccessible(true);
			Object objOther = f.get(obj);
			return getFieldValue(objOther, nameOther);
		}
		java.lang.reflect.Field f = obj.getClass().getDeclaredField(fieldName);
		f.setAccessible(true);
		Object showObj = f.get(obj);
		return showObj;
	}
	
	/**
	 * 把一个对象中所为类型是字符串，值为null或空值的域值进行替换
	 * @param obj 对象
	 * @param show 替换值
	 */
	public static void killNull(Object obj, String show)
	{
		Class<? extends Object> objClass = obj.getClass();
		Field[] fields = objClass.getDeclaredFields();
		for (int i = 0; i < fields.length; i++)
		{
			Field f = fields[i];
			if (String.class == f.getType())
			{
				try
				{
					f.setAccessible(true);
					String value = (String) f.get(obj);
					if (value == null || "".equals(value))
					{
						f.set(obj, show);
					}
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}
	}
	

	/**
	 * 两个对象属性值copy
	 * @param fromObj 来源对象
	 * @param toObj 目标对象
	 * @param exceptFieldNames 排除的属性名称。
	 */
	public static void copyObjectField(Object fromObj,Object toObj, String... exceptFieldNames)
	{
		Class<? extends Object> objClass = fromObj.getClass();
		if(!objClass.isInstance(toObj))
		{//如果类型不同，则返回
			return;
		}
		Field[] fields = objClass.getDeclaredFields(); //返回所有字段，不包括继承的
		for (int i = 0; i < fields.length; i++)
		{
			Field f = fields[i];
			f.setAccessible(true);
			try
			{
				String name = f.getName(); //属性名称
				if(exceptFieldNames!=null)
				{
					boolean except = false; //是否排除
					for(String exceptFieldName:exceptFieldNames)
					{
						if(name.equals(exceptFieldName))
						{
							except = true;
							break;
						}
					}
					if(except)
					{
						continue;
					}
				}
				
				f.set(toObj, f.get(fromObj)); //属性值copy
				
			}catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 给对象的指定属性赋值。
	 * 
	 * @param obj	对象
	 * @param fieldName	属性名称
	 * @param value	属性值
	 */
	public static void setValue(Object obj,String fieldName,Object value) 
	{
		try
		{
			Field f = obj.getClass().getDeclaredField(fieldName);
			f.setAccessible(true);
			f.set(obj, value);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
	}
	
	/**
	 * @return 返回Gson对象
	 */
	public static Gson getGson()
	{
		return new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
	}
	
    /**
     * 根据给定日期 和 天数，得到相对日期
     * @param date 指定日期
     * @param day 天数，如果是正数，表示得到几天后的时间，如果是负值，表示得到几天前的时间。
     * @return
     */
    public static Date getDate(Date date, int day) {  
    	if(date==null)
    	{
    		date=new Date();
    	}
        Calendar now =Calendar.getInstance();  
        now.setTime(date);  
        now.set(Calendar.DATE,now.get(Calendar.DATE)+day);  
        return now.getTime(); 
    }  
    

	/**
	 * 将整数转换为指定长度的字符串返回，如果长度不够，前面补0</br>常用作生成编号
	 * @param num 要转换的数值
	 * @param len 转换后的长度
	 * @return
	 */
	public static String int2Str(int num, int len)
	{
		String numStr = num + "";
		int ll = numStr.length();
		StringBuffer buf = new StringBuffer("");
		if (ll < len)
		{
			while (ll++ < len)
			{
				buf.append("0");
			}
		}

		return buf + numStr;
	}
}